using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using SBPweb.Modules.Modularity;
using SBPweb.Contracts;

using SBPweb.Presentation.Windows.Forms.Controls;
using SBPweb.Contracts.Implementation;

namespace SBPweb.Modules.Options.Controls
{
	public partial class OptionsForm : DockingUserControl
	{

		#region Private properties

		private bool mIsModified;
		private Size mFloatingMinimumSize = new Size(330, 260);
		private OptionsModule mParentModule;
		private PersistencyDictionary mState;

		#endregion

		#region Constructor logic

		public OptionsForm(OptionsModule parentModule)
            : base(parentModule)
		{
			mParentModule = parentModule;
			InitializeComponent();
			(this as System.Windows.Forms.Control).Text = Localization.LocalizationExtender.GetString("bsiOptions.Text");

            micOptions = new MenuItemControl();
            micOptions.Name = "micOptions";
            micOptions.Text = "Options";
            micOptions.Image = Properties.Resources.ControlPanel.ToBitmap();
            micOptions.ImageScaling = ToolStripItemImageScaling.None;
            micOptions.Click += new EventHandler(micOptions_Click);
            localizationExtender1.SetResourceKey(this.micOptions, "micOptions");

            parentModule.Host.Menu.Insert(2, micOptions);

			SBPweb.Localization.LocalizationExtender.OnInvalidatingControls += new EventHandler(LocalizationExtender_OnInvalidatingControls);

			Resize += new EventHandler(OptionsForm_Resize);
			VisibleChanged += new EventHandler(OptionsForm_VisibleChanged);
		
			this.Dock = DockStyle.Fill;
            this.InitialAppearanceStyle = SBPweb.Modules.Smartparts.AppearanceStyle.Float;
            this.IsModal = true;
            this.IsShowInWindowMenu = false;
            this.AllowDockBottom = false;
            this.AllowDockCenter = false;
            this.AllowDockLeft = false;
            this.AllowDockRight = false;
            this.AllowDockTop = false;
            this.AllowFloat = true;
		}

		void OptionsForm_VisibleChanged(object sender, EventArgs e)
		{
			if (mState != null)
			{
				LoadPersistence(mState);
			}

			if (this.ParentForm != null)
			{
				ParentForm.KeyDown -= new KeyEventHandler(ParentForm_KeyDown);
				ParentForm.KeyPreview = true;
				ParentForm.KeyDown += new KeyEventHandler(ParentForm_KeyDown);
			}
		}

		void ParentForm_KeyDown(object sender, KeyEventArgs e)
		{
			if (e.KeyCode == Keys.Escape)
			{
				btnCancel_Click(sender, EventArgs.Empty);
			}
		}

        void micOptions_Click(object sender, EventArgs e)
        {
			IsVisible = true;
        }

		void OptionsForm_Resize(object sender, EventArgs e)
		{
			if (this.Parent != null)
			{
				this.Parent.MinimumSize = this.mFloatingMinimumSize;
			}
		}

		private void LocalizationExtender_OnInvalidatingControls(object sender, EventArgs e)
		{
            if (Parent!=null)
			    Parent.Text = micOptions.Text = SBPweb.Localization.LocalizationExtender.GetString(this, "micOptions.Text");
		}

		#endregion

		#region Public properties

		public bool IsModified
		{
			get
			{
				return mIsModified;
			}
			set
			{
				bool prevIsModified = mIsModified;
				mIsModified = value;
				btnApply.Enabled = value;

				if (OnModify != null && mIsModified && !prevIsModified)
				{
					OnModify.Invoke(this, null);
				}
			}
		}

		#endregion

		#region Public methods

		public void AddTabPage(string name, string text, Control control)
		{
			if (string.IsNullOrEmpty(name))
			{
				throw new ArgumentNullException("Tabpage name cannot be empty on the Options form.");
			}
			if (control == null)
			{
				throw new ArgumentNullException("Control cannot be null on the options form.");
			}

			if (tcPages.InvokeRequired)
			{
				tcPages.BeginInvoke(new InvokedAddTabPage(AddTabPage), name, text, control);
				return;
			}

			if (tcPages.TabPages[name] != null)
			{
				throw new ArgumentException("Control with the same key is exists in the options form.");
			}

			try
			{
				TabPage tabPage = new TabPage();
				control.Location = new Point();
				Panel pnl = new Panel();
				pnl.Name = "pnl";
				pnl.AutoScroll = true;
				pnl.Dock = DockStyle.Fill;
				pnl.Controls.Add(control);
				//control.Dock = DockStyle.Fill;
				
				tabPage.Controls.Add(pnl);
				tabPage.AutoSize = true;
				tabPage.Name = name;
				tabPage.Text = text;
				tcPages.TabPages.Add(tabPage);
			}
			catch (Exception ex)
			{
				throw new Exception("Control cannot be added to the options form as tabpage.", ex);
			}
		}

		public void RenameTabPage(string name, string newText)
		{
			if (tcPages.InvokeRequired)
			{
				tcPages.BeginInvoke(new InvokedRenameTabPage(RenameTabPage), name, newText);
				return;
			}

			if (tcPages.TabPages != null)
			{
				foreach (TabPage tp in tcPages.TabPages)
				{
					if (tp.Name == name)
					{
						tp.Text = newText;
						break;
					}
				}
			}
		}

		public void RemoveTabPage(string name)
		{
			if (tcPages.InvokeRequired)
			{
				tcPages.BeginInvoke(new InvokedRemoveTabPage(RemoveTabPage), name);
				return;
			}

			if (tcPages.TabPages != null)
			{
				TabPage tabPage = new TabPage();
				foreach (TabPage tp in tcPages.TabPages)
				{
					if (tp.Name == name)
					{
						tabPage = tp;
						break;
					}
				}
				tcPages.TabPages.Remove(tabPage);
			}
		}

		#endregion

		#region Events

		internal event EventHandler OnModify;
		internal event EventHandler OnApply;
		internal event EventHandler OnCancel;

		#endregion

		#region Additional invocation delegates

		private delegate void InvokedAddTabPage(string name, string text, Control control);

		private delegate void InvokedRenameTabPage(string name, string newText);

		private delegate void InvokedRemoveTabPage(string name);

		#endregion

		#region UI event handlers

		private void btnApply_Click(object sender, EventArgs e)
		{
			btnApply.Enabled = false;

			if (OnApply != null)
			{
				OnApply.Invoke(this, EventArgs.Empty);
			}

			IsModified = false;

            if (CurrentAppearanceStyle == SBPweb.Modules.Smartparts.AppearanceStyle.Float)
            {
                ParentForm.BringToFront();
            }
		}

		private void btnCancel_Click(object sender, EventArgs e)
		{
			if (OnCancel != null)
			{
				OnCancel(this, EventArgs.Empty);
			}

			IsModified = false;
			//this.DialogResult = DialogResult.Cancel;
            IsVisible = false;
        }

		private void btnOK_Click(object sender, EventArgs e)
		{
			if (IsModified)
			{
				btnApply_Click(sender, e);
			}
			//this.DialogResult = DialogResult.OK;
            IsVisible = false;
		}

		#endregion

		#region Persistency

		internal void SavePersistence(PersistencyDictionary state)
		{
			if (this.Parent != null)
			{
				state.SetInt("OptionsWidth", this.Parent.Width);
				state.SetInt("OptionsHeight", this.Parent.Height);
			}
		}

		internal void LoadPersistence(PersistencyDictionary state)
		{
			mState = state;
			int width = state.GetInt("OptionsWidth", this.Width);
			int height = state.GetInt("OptionsHeight", this.Height);
			if (width > 0 && width > this.MinimumSize.Width
				&&
				height > 0 && height > this.MinimumSize.Height
				&&
				this.Parent != null)
			{
				this.Parent.Size = new Size(width, height);
				if (this.ParentForm != null)
				{
					this.ParentForm.Size = new Size(this.Parent.Width + 8, this.Parent.Height + 25);
					Form mainForm = ParentModule.Host as Form;
					if (mainForm != null)
					{
						this.ParentForm.Location = new Point(mainForm.Left + (mainForm.Width - this.ParentForm.Width) / 2, mainForm.Top + (mainForm.Height - this.ParentForm.Height) / 2);
					}
				}
				this.Size = new Size(width, height);
			}
		}

		#endregion

	}
}
